package io.renren.modules.demo.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.renren.modules.demo.algorithm.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@RestController
@CrossOrigin
@RequestMapping("/algo")
@Slf4j
public class AlgoController {
    @PostMapping()
    public String algo(HttpServletRequest request, @RequestBody JSONObject jsonObject){
        long time1 = new Date().getTime();
        String warehouses = jsonObject.getString("warehouses").replaceAll("=", ":");
        System.out.println(warehouses);
        JSONArray warehousesObj = JSON.parseArray(warehouses);
        int warehouseNumber =warehousesObj.size();
        for(int i = 0; i < warehouseNumber; i++)
        {
            JSONObject o = (JSONObject)warehousesObj.get(i);
            Warehouse warehouse = new Warehouse();
            warehouse.setDemand((Integer) o.get("demand"));
            warehouse.setLocationX((Integer) o.get("locationX"));
            warehouse.setLocationY((Integer) o.get("locationY"));
            warehouse.setSerialNumber(i + 1);  //设置序号
            CarScheduling.getWarehouseArrayList().add(warehouse);  //加到ArrayList中
        }


        String cars = jsonObject.getString("cars").replaceAll("=",":");
        System.out.println(cars);
        JSONArray carObjects = JSON.parseArray(cars);
//        for (int i = 0; i < carObjects.size(); i++) {
//            JSONObject o = (JSONObject)carObjects.get(i);
//            Integer useCost = (Integer) o.get("useCost");
//        }
        int carNumber = carObjects.size();
        for(int i = 0; i < carNumber; i++)
        {
            Car car = new Car();
            car.setSerialNumber(i + 1);  //设置序号
            JSONObject o = (JSONObject)carObjects.get(i);
            car.setUseCost((Integer) o.get("useCost"));
            car.setCostPerKilometer((Integer)o.get("costPerKilometer"));
            car.setCarryingCapacity((Integer)o.get("carryingCapacity"));
            CarScheduling.getCarArrayList().add(car);  //加到ArrayList中
        }
        for (Warehouse warehouse : CarScheduling.getWarehouseArrayList()) {
            System.out.println(warehouse.toString());
        }
        for (Car car : CarScheduling.getCarArrayList()) {
            System.out.println(car.toString());
        }

        int[][] distance = new int[CarScheduling.getWarehouseArrayList().size() + 1][CarScheduling.getWarehouseArrayList().size() + 1];  //编号从1开始
        for(int i = 1; i < CarScheduling.getWarehouseArrayList().size() + 1; i++)
        {
            for(int j = i + 1; j < CarScheduling.getWarehouseArrayList().size() + 1; j++)
            {
                distance[i][j] = calculateDistance(CarScheduling.getWarehouseArrayList().get(i - 1), CarScheduling.getWarehouseArrayList().get(j - 1));
            }
        }
        CarScheduling.setDistance(distance);

        int populationNumber = 200;  //种群数量
        int inheritNumber = 100;  //遗传迭代次数
        int simulatedAnnealingNumber = 150;  //模拟退火次数

        Population population = new Population();
        population.Initialize(populationNumber);

        for(int i = 0; i < inheritNumber; i++)
        {
            Population childrenPopulation = Inherit.GenerateChildrenPopulation(population, 0.1, 0.9);
            SimulatedAnnealing.SimulatedAnnealingChildrenPopulation(simulatedAnnealingNumber, childrenPopulation.getPopulation(),
                    100, 0.99, 0.2, 0.6, 0.2);
            childrenPopulation.CalculateFitnessSum();
            population.setPopulation(childrenPopulation.getPopulation());
            population.setFitnessSum(childrenPopulation.getFitnessSum());
        }

        double maxFitness = 0;
        int index = 0;
        for(int j = 0; j < population.getPopulation().size(); j++)
        {
            if(population.getPopulation().get(j).getFitness() > maxFitness)
            {
                maxFitness = population.getPopulation().get(j).getFitness();
                index = j;
            }
        }
        Chromosome bestChromosome = population.getPopulation().get(index);

        long time2 = new Date().getTime();
        long costTime = time2 - time1;
        System.out.println("所用时间为:" + costTime);
        int[] distanceAndCost = bestChromosome.TotalDistanceAndCost();
        System.out.println("距离：" + distanceAndCost[0]);
        System.out.println("费用：" + distanceAndCost[1]);
        System.out.println("使用车辆数：" + bestChromosome.TotalCarNumberInUse());

        String s = bestChromosome.toString();
        CarScheduling.Initialize();

        return s;
    }

    public static int calculateDistance(Warehouse warehouse1, Warehouse warehouse2)
    {
        return Math.abs(warehouse1.getLocationX() - warehouse2.getLocationX()) + Math.abs(warehouse1.getLocationY() - warehouse2.getLocationY());
    }
}
